#ifndef _WT_COLLECTION_H
#define _WT_COLLECTION_H

/* Structure that determines how objects are matched in the collection */

typedef int (WtClnCompareProc) (Tcl_Obj *, Tcl_Obj *);
typedef Tcl_Obj *(WtClnGetKeyProc) (Tcl_Obj *);
typedef Tcl_Obj *(WtClnGetValueProc) (Tcl_Obj *);

typedef struct WtClnItemTypeT {
  WtClnCompareProc *compare;
  WtClnGetKeyProc *getKey;
  WtClnGetValueProc *getValue;
} WtClnItemType;

/* WtCollection obejct */

typedef struct WtCollectionT {
  WtClnItemType *itemType;
  Tcl_Obj *list;
} WtCollection;

WtCollection *WtToCln(Tcl_Obj *obj);
Tcl_Obj *WtNewClnObj(WtClnItemType *itemType);
int WtClnSize(Tcl_Obj *cln);
Tcl_Obj *WtGetClnItemAtIndex(Tcl_Obj *cln, int idx);
void WtSetClnItemAtIndex(Tcl_Obj *cln, int idx, Tcl_Obj *obj);
void WtAppendClnItem(Tcl_Obj *cln, Tcl_Obj *obj);
void WtAppendAllClnItems(Tcl_Obj *cln, Tcl_Obj *list);
int WtCompareClnItem(Tcl_Obj *cln, Tcl_Obj *item, Tcl_Obj *key);
Tcl_Obj *WtGetClnItemKey(Tcl_Obj *cln, Tcl_Obj *item);
Tcl_Obj *WtGetClnItemValue(Tcl_Obj *cln, Tcl_Obj *item);
Tcl_Obj *WtGetClnItems(Tcl_Obj *cln);
Tcl_Obj *WtGetClnKeys(Tcl_Obj *cln);
Tcl_Obj *WtGetClnValues(Tcl_Obj *cln);
Tcl_Obj *WtFindClnItemIndex(Tcl_Obj *cln, Tcl_Obj *key, int start, int *index);
Tcl_Obj *WtFindClnItemIndexReverse(Tcl_Obj *cln, Tcl_Obj *key, int start, int *index);
Tcl_Obj *WtFindClnItem(Tcl_Obj *cln, Tcl_Obj *key);
Tcl_Obj *WtFindAllClnItems(Tcl_Obj *cln, Tcl_Obj *key);
Tcl_Obj *WtFindAllClnKeys(Tcl_Obj *cln, Tcl_Obj *key);
Tcl_Obj *WtFindAllClnValues(Tcl_Obj *cln, Tcl_Obj *key);
void WtRemoveFromCln(Tcl_Obj *cln, Tcl_Obj *target, int limit);
void WtRemoveFromClnByIndex(Tcl_Obj *cln, int idx);
void WtRemoveFromClnByKey(Tcl_Obj *cln, Tcl_Obj *key, int limit);
void WtRemoveFromClnByKeyList(Tcl_Obj *cln, Tcl_Obj *list, int limit);
void WtClearCollection(Tcl_Obj *cln);

extern Tcl_ObjType WtClnType;

#endif /* !_WT_COLLECTION_H */
